package com.idna.wsconsumer.axis2;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;


import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAPProcessingException;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.apache.commons.logging.impl.SimpleLog;

import com.idna.wsconsumer.utils.ApplicationUtil;
import com.idna.wsconsumer.utils.ApplicationUtilImpl;

public class Axis2Client implements Runnable
{
	private String ep = null;
	private ApplicationUtil utils = null;
	private Properties prop = null;
	private String xmlRequest = null;
	private String operation = null;
	private String productApi = null;
	public static final SimpleLog LOGGER = new SimpleLog("");
	
	public Axis2Client(String api, String operation)
	{
		this.productApi = api;
		this.operation = operation;
	}
	public void init(String rootElement)
	{
		try
		{
			utils = new ApplicationUtilImpl();
			prop = utils.loadProperty(ApplicationUtilImpl.PROP_PATH);
			ep = prop.getProperty(rootElement.trim().toLowerCase()+"_endpoint");
			xmlRequest = utils.readFile(ApplicationUtilImpl.RESOURCES + "xmlrequests/" + prop.getProperty(rootElement.trim().toLowerCase()+"_xmlrequest"));
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
			System.exit(-1);
		} 
		catch (IOException e)
		{
			e.printStackTrace();
			System.exit(-1);
		}
	}

	public void run()
	{
		try
		{
			init(productApi);
			Options options = new Options();
			options.setTo(new EndpointReference(ep));
			RPCServiceClient client = new RPCServiceClient();
			client.setOptions(options);
			
			System.out.println("Thread: "+Thread.currentThread().getName()+"-> Waiting for response from server side...");
			OMElement response;
			
			if(productApi.equalsIgnoreCase("netid"))
			{	
				response = client.invokeBlocking(new QName(operation), new String[]{xmlRequest, "1"});
			}
			else
			{
				long before = System.currentTimeMillis();
				response = client.invokeBlocking(new QName(operation), new String[]{xmlRequest});
				long after = System.currentTimeMillis();
				LOGGER.info("This transaction takes: " + (after-before) + "ms. ");
			}
			
			LOGGER.info("Thread: "+Thread.currentThread().getName()+"-> Response: \n");
			System.out.println(response.toString().replaceAll("&lt;", "<"));
			LOGGER.info("Thread: "+Thread.currentThread().getId()+"-> going to sleep for 20 milliseconds.\n");
			Thread.sleep(20);
		}
		catch (AxisFault e)
		{
			e.printStackTrace();
		}
		catch (SOAPProcessingException e)
		{
			e.printStackTrace();
		}
		catch (FactoryConfigurationError e)
		{
			e.printStackTrace();
		}
		catch (InterruptedException e)
		{
			e.printStackTrace();
		}
		LOGGER.info("Thread " + Thread.currentThread().getName() + " sleeping done.\n");
	}

	public static void main(String[] args)
	{
		//Axis2Client client1 = new Axis2Client("proveid", "search");
		//Axis2Client client2 = new Axis2Client("documentid", "search");
		Axis2Client client3 = new Axis2Client("proveid", "search");
		//Axis2Client client4 = new Axis2Client("callid", "search");
		//Axis2Client client5 = new Axis2Client("callid", "execute");
		
		ExecutorService threadExecutor = Executors.newFixedThreadPool(5);
		
		//threadExecutor.execute(client1);
		//threadExecutor.execute(client2);
		threadExecutor.execute(client3);
		//threadExecutor.execute(client4);
		//threadExecutor.execute(client5);
		
		threadExecutor.shutdown();
	}
}
